package indexer;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import dao.DocumentDAO;
import dao.PostDAO;
import dao.VocabularyDAO;
import domain.Document;
import domain.Post;
import domain.Vocabulary;

public class FileBufferPopulator {
	private DocumentDAO documentDAO;
	private VocabularyDAO vocabularyDAO;
	private PostDAO postDAO;
	private List<Vocabulary> dbVocabulary; // the vocabulary stored in the database
	private List<Vocabulary> docVocabulary; // the vocabulary of the document

	public FileBufferPopulator() throws ClassNotFoundException, IOException {
		documentDAO = new DocumentDAO();
		postDAO = new PostDAO();
		vocabularyDAO = new VocabularyDAO();
		dbVocabulary = new ArrayList<Vocabulary>();
	}

	public void populateVocabulary(List<Vocabulary> v, Document document)
			throws ClassNotFoundException, IOException {
		this.docVocabulary = v;
		initializeVocabulary();
		insertDocument(document);
		populate();
	}

	private void initializeVocabulary() throws ClassNotFoundException, IOException {
		dbVocabulary = vocabularyDAO.select(new Vocabulary());
		// set the post list for each vocabulary
		try {
			for (Vocabulary voc : dbVocabulary) {
				voc.setPostList(postDAO.onSelect(voc));
			}
		} catch (SQLException ex) {
			ex.printStackTrace();
			System.out.println("Error while trying to get the post list for the vocabularies: "
					+ ex.getMessage());
		}
	}

	private void populate() {
		int index = -1;
		for (Vocabulary voc : docVocabulary) {
			index = dbVocabulary.indexOf(voc);
			if (index == -1)
				insertVocabulary(voc);
			else
				updateVocabulary(dbVocabulary.get(index), voc);
		}
	}

	private void insertDocument(Document document) {
		documentDAO.insert(document);
		List<Document> aux = documentDAO.select(document);
		if (aux != null && !aux.isEmpty()) {
			document.setId(aux.get(0).getId());
		}
	}

	private void updateVocabulary(Vocabulary oldVoc, Vocabulary newVoc) {
		if (oldVoc.getMaxFrequency() < newVoc.getMaxFrequency())
			oldVoc.setMaxFrequency(newVoc.getMaxFrequency());
		oldVoc.getPostList().addAll(newVoc.getPostList());
		vocabularyDAO.update(oldVoc);
		insertPost(newVoc.getPostList(), oldVoc);
	}

	private void insertVocabulary(Vocabulary v) {
		vocabularyDAO.insert(v);
		List<Vocabulary> aux = vocabularyDAO.select(v);
		v.setId(aux.get(0).getId());
		dbVocabulary.add(v);
		insertPost(v.getPostList(), v);
	}

	private void insertPost(List<Post> post, Vocabulary v) {
		for (Post p : post) {
			postDAO.insertForVocabulary(p, v);
		}
	}

	/**
	 * Acceso a docVocabulary
	 * @return valor del atributo docVocabulary
	 */
	public List<Vocabulary> getDocVocabulary() {
		return docVocabulary;
	}
}
